package coreCron

import (
	"gitee.com/igolang/imoney/internal/core/logger"
	"gitee.com/igolang/pkg/xcron"
	"github.com/robfig/cron/v3"
	"github.com/spf13/cast"
	"slices"
	"strings"
	"time"
)

type cronLogger struct {
}

func (s *cronLogger) Info(msg string, keysAndValues ...any) {
	keysAndValues = s.formatKeyValues(keysAndValues)
	logger.Log().Info("cron.info:"+msg, keysAndValues...)
}

func (s *cronLogger) Error(err error, msg string, keysAndValues ...any) {
	keysAndValues = s.formatKeyValues(keysAndValues)
	keysAndValues = append(keysAndValues, "err", err)
	logger.Log().Error("cron.err:"+msg, keysAndValues...)
}

func (s *cronLogger) formatKeyValues(keysAndValues []any) []any {
	if len(keysAndValues) == 0 {
		return keysAndValues
	}
	m := s.formatKeyValuesMap(keysAndValues)
	val, ok := m["entry"]
	if ok {
		id := val.(cron.EntryID)
		list := List()
		index := slices.IndexFunc(list, func(en *xcron.Entry) bool {
			return en.ID == id
		})

		if index > -1 {
			entry := list[index]
			keysAndValues = append(keysAndValues,
				"entryKey", entry.Key,
				"entryName", entry.Name,
				"entryDesc", entry.Desc,
				"entrySpec", entry.Spec,
			)
		}
	}

	return s.formatTimes(keysAndValues)
}

func (s *cronLogger) formatKeyValuesMap(keysAndValues []any) map[string]any {
	result := make(map[string]any)
	if len(keysAndValues) == 0 {
		return result
	}
	numKeysAndValues := len(keysAndValues)
	for i := 0; i < numKeysAndValues; i++ {
		if i%2 == 0 {
			result[cast.ToString(keysAndValues[i])] = keysAndValues[i+1]
		}
	}
	return result
}

func (s *cronLogger) formatTimes(keysAndValues []any) []any {
	var formattedArgs []any
	for _, arg := range keysAndValues {
		if t, ok := arg.(time.Time); ok {
			arg = t.Format(time.DateTime)
		}
		formattedArgs = append(formattedArgs, arg)
	}
	return formattedArgs
}

func (s *cronLogger) formatString(numKeysAndValues int) string {
	var sb strings.Builder
	for i := 0; i < numKeysAndValues/2; i++ {
		if i > 0 {
			sb.WriteString(", ")
		}
		sb.WriteString("%v:%v")
	}
	return sb.String()
}
